package com.dongdong.bookstore.module.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dongdong.bookstore.common.service.RedisService;
import com.dongdong.bookstore.module.ums.mapper.AdminMapper;
import com.dongdong.bookstore.module.ums.mapper.ResourceMapper;
import com.dongdong.bookstore.module.ums.model.Admin;
import com.dongdong.bookstore.module.ums.model.AdminRoleRelation;
import com.dongdong.bookstore.module.ums.model.Menu;
import com.dongdong.bookstore.module.ums.model.Resource;
import com.dongdong.bookstore.module.ums.service.AdminRoleRelationService;
import com.dongdong.bookstore.module.ums.service.AdminService;
import com.dongdong.bookstore.module.ums.service.ResourceService;
import com.dongdong.bookstore.module.ums.service.UmsCacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author chiangkai
 * @date 2021-10-24
 * @email chiangkk@163.com
 */
@Service
public class UmsCacheServiceImpl implements UmsCacheService {

    @Autowired
    private AdminService adminService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private AdminRoleRelationService adminRoleRelationService;
    @Value("${redis.database}")
    private String REDIS_DATABASE;
    @Value("${redis.expire.common}")
    private Long REDIS_EXPIRE;
    @Value("${redis.key.admin}")
    private String REDIS_KEY_ADMIN;
    @Value("${redis.key.resourceList}")
    private String REDIS_KEY_RESOURCE_LIST;
    @Value("${redis.key.menu}")
    private String REDIS_KEY_MENU_LIST;

    @Override
    public void delAdmin(Long adminId) {
        Admin admin = adminService.getById(adminId);
        if (admin != null) {
            String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + admin.getUsername();
            redisService.del(key);
        }
    }

    @Override
    public void delAdmin(String username) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + username;
        redisService.del(key);
    }

    @Override
    public void delResourceList(Long adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + adminId;
        redisService.del(key);
    }

    @Override
    public void delResourceListByRole(Long roleId) {
        QueryWrapper<AdminRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AdminRoleRelation::getRoleId, roleId);
        List<AdminRoleRelation> relationList = adminRoleRelationService.list(wrapper);
        if (CollUtil.isNotEmpty(relationList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = relationList.stream().map(relation -> keyPrefix + relation.getAdminId()).collect(Collectors.toList());
            redisService.del(keys);
        }
    }

    @Override
    public void delResourceListByRoleIds(List<Long> roleIds) {
        QueryWrapper<AdminRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(AdminRoleRelation::getRoleId, roleIds);
        List<AdminRoleRelation> relationList = adminRoleRelationService.list(wrapper);
        if (CollUtil.isNotEmpty(relationList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = relationList.stream().map(relation -> keyPrefix + relation.getAdminId()).collect(Collectors.toList());
            redisService.del(keys);
        }
    }

    @Override
    public void delResourceListByResource(Long resourceId) {
        //通过资源ID获取用户ID
        List<Long> adminIdList = adminMapper.getAdminIdList(resourceId);
        if (CollUtil.isNotEmpty(adminIdList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = adminIdList.stream().map(adminId -> keyPrefix + adminId).collect(Collectors.toList());
            redisService.del(keys);
        }
    }

    @Override
    public Admin getAdmin(String username) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + username;
        return (Admin) redisService.get(key);
    }

    @Override
    public void setAdmin(Admin admin) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + admin.getUsername();
        redisService.set(key, admin, REDIS_EXPIRE);
    }

    @Override
    public List<Resource> getResourceList(Long adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + adminId;
        return (List<Resource>) redisService.get(key);
    }

    @Override
    public void setResourceList(Long adminId, List<Resource> resourceList) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + adminId;
        redisService.set(key, resourceList, REDIS_EXPIRE);
    }

    @Override
    public List<Resource> getResourceListAll() {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + "all";
        List<Resource> list = (List<Resource>) redisService.get(key);
        if (CollUtil.isEmpty(list)) {
            list = resourceService.list();
            if (CollUtil.isNotEmpty(list)) {
                setResourceListAll(list);
            }
        }
        return list;
    }


    @Override
    public void clearResourcesListAll() {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + "all";
        redisService.del(key);
    }

    @Override
    public void setResourceListAll(List<Resource> resourceList) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + "all";
        redisService.set(key, resourceList, REDIS_EXPIRE);
    }

    @Override
    public List<Menu> getMenuListByAdminId(Long adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_MENU_LIST + ":" + adminId;
        return (List<Menu>) redisService.get(key);
    }

    @Override
    public void setMenuListByAdminId(Long adminId, List<Menu> menuList) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_MENU_LIST + ":" + adminId;
        redisService.set(key, menuList);
    }

    @Override
    public void clearMenuListAll() {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_MENU_LIST + ":" + "*";
        Set<String> keys =  redisService.getStringCommonKey(key);
        redisService.del(keys);
    }

    @Override
    public void clearMenuListByAdminId(Long adminId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_MENU_LIST + ":" + adminId;
        redisService.del(key);
    }
}
